import re
import time
import json
import simplejson
from api.base import *
from api.folder import *
from common.logger import logger
from common.retcode import RetCode
from common.types import FileInfo, PathInfo, FolderTree, ShareInfo
from common.models import FileList, PathList, TreeList

class ShareAction(FolderAction):
	def __init__(self, sess_wp: SessionWrapper):
		super(ShareAction, self).__init__(sess_wp)

	def share_file(self, fid, et, ac):
		'''分享文件'''

		# 分享有效期：1 - 1天，2 - 7天，3 - 永久
		expireTime_dict = {
			1: "1", 
			2: "7", 
			3: "2099"
		}

		expireTime = None
		if et and et in expireTime_dict:
			expireTime = et
		else:
			return RetCode.PARAMS_ERROR

		# 分享形式：1、私密分享，2、公开分享
		withAccessCode = None
		if ac and ac in (1, 2):
			withAccessCode = ac
		else:
			return RetCode.PARAMS_ERROR

		if withAccessCode == 1:
			url = self._host_url + "/v2/privateLinkShare.action"
			params = {
				"fileId": str(fid),
				"expireTime": expireTime_dict[expireTime],
				"withAccessCode": str(withAccessCode)
			}
		else:
			url = self._host_url + "/v2/createOutLinkShare.action"
			params = {
				"fileId": str(fid),
				"expireTime": expireTime_dict[expireTime]
			}
		resp = self._get(url=url, params=params)
		if not resp:
			logger.error(f"Share file: {fid} network error!")
			return RetCode.FAILED
		
		resp = resp.json()
		share_url = resp['shortShareUrl']
		pwd = resp['accessCode'] if 'accessCode' in resp else ''
		return RetCode.SUCCESS, (share_url, pwd)

	def list_shared_url(self, stype: int, page: int = 1) -> FileList:
		"""列出自己的分享文件、转存的文件链接
		:param stype:  1 发出的分享，2 收到的分享
		:param page:   页面，60 条记录一页
		:return:        FileList 类
		"""
		get_url = self._host_url + "/v2/listShares.action"
		data = []
		while True:
			params = {"shareType": stype, "pageNum": page, "pageSize": 60}
			resp = self._get(get_url, params=params)
			if not resp:
				logger.error("List shared: network error!")
				return None
			resp = resp.json()
			data_, done = self._get_more_page(resp)
			data.extend(data_)
			if done:
				break
			page += 1
			time.sleep(0.5)  # 大量请求可能会被限制
		results = FileList()
		for item in data:
			name = item['fileName']
			id_ = item['fileId']
			ctime = item['shareTime']
			size = item['fileSize']
			ftype = item['fileType'] if 'fileType' in item else ''
			isFolder = item['isFolder']
			pwd = item['accessCode'] if 'accessCode' in item else ''
			copyC = item['accessCount']['copyCount'] if 'accessCount' in item else 0
			downC = item['accessCount']['downloadCount'] if 'accessCount' in item else 0
			prevC = item['accessCount']['previewCount'] if 'accessCount' in item else 0
			url = item['accessURL']
			durl = item['downloadUrl'] if 'downloadUrl' in item else ''
			path = item['filePath']
			need_pwd = item['needAccessCode'] if 'needAccessCode' in item else 0
			s_type = item['shareType']
			s_mode = item['shareMode']
			r_stat = item['reviewStatus']

			results.append(ShareInfo(name=name, id=id_, ctime=ctime, size=size, ftype=ftype,
									 isFolder=isFolder, pwd=pwd, copyC=copyC, downC=downC, prevC=prevC,
									 url=url, durl=durl, path=path, need_pwd=need_pwd, s_type=s_type,
									 s_mode=s_mode, r_stat=r_stat))

		return results

	def get_share_folder_info(self, share_id, verify_code, pwd='undefined'):
		"""获取分享的文件夹信息"""
		result = []
		page = 1
		info_url = self._host_url + '/v2/listShareDir.action'
		while True:
			params = {
				'shareId': share_id,
				'verifyCode': verify_code,
				'accessCode': pwd or 'undefined',
				'orderBy': 1,
				'order': 'ASC',
				'pageNum': page,
				'pageSize': 60
			}
			resp = requests.get(info_url, params=params, headers=self._headers, verify=False)
			if not resp:
				return None
			resp = resp.json()
			if 'errorVO' in resp:
				print("是文件夹，并且需要密码或者密码错误！")
				logger.debug("Access password is required!")
				return None
			for item in resp['data']:
				durl = 'https:' + item['downloadUrl'] if 'downloadUrl' in item else ''
				print('#', item['fileId'], '文件名', item['fileName'], item['fileSize'], durl)
			if resp['recordCount'] <= resp['pageSize'] * resp['pageNum']:
				break

			page += 1
		print(f"共 {resp['recordCount']} 条记录")
		return result

	def get_share_file_info(self, share_id, pwd=''):
		"""获取分享的文件信息"""
		verify_url = self._host_url + "/shareFileVerifyPass.action"
		params = {
			'fileVO.id': share_id,
			'accessCode': pwd
		}
		resp = requests.get(verify_url, params=params, verify=False)
		if not resp:
			return None
		resp = resp.json()
		if not resp:
			print("是文件，并且需要密码或者密码错误！")
			return None
		f_id = resp['fileId']
		f_name = resp['fileName']
		f_size = resp['fileSize']
		f_type = resp['fileType']
		durl = resp['longDownloadUrl']

		return (f_id, f_name, f_size, f_type, durl)

	def get_file_info_by_url(self, share_url, pwd=''):
		"""通过分享链接获取信息"""

		first_page = requests.get(share_url, headers=self._headers, verify=False)
		if not first_page:
			logger.error("File info: network error!")
			return None
		first_page = first_page.text
		# 抱歉，您访问的页面地址有误，或者该页面不存在
		if '您访问的页面地址有误' in first_page:
			logger.debug(f"The sharing link has been cancelled {share_url}")
			return None
		if 'window.fileName' in first_page:  # 文件
			share_id = re.search(r'class="shareId" value="(\w+?)"', first_page).group(1)
			# 没有密码，则直接暴露 durl
			durl = re.search(r'class="downloadUrl" value="(\w+?)"', first_page)
			if durl:
				durl = durl.group(1)
				print('直链：', durl)
				return None
			is_file = True
		else:  # 文件夹
			share_id = re.search(r"_shareId = '(\w+?)';", first_page).group(1)
			verify_code = re.search(r"_verifyCode = '(\w+?)';", first_page).group(1)
			is_file = False

		if is_file:
			return self.get_share_file_info(share_id, pwd)
		else:
			return self.get_share_folder_info(share_id, verify_code, pwd)